local frame
local OptionHouse
local TOTAL_ROWS = 14

local STATUS_COLORS = {
	["DISABLED"] = "|cff9d9d9d",
	["NOT_DEMAND_LOADED"] = "|cffff8000",
	["LOAD_ON_DEMAND"] = "|cff1eff00",
	["DISABLED_AT_RELOAD"] = "|cffa335ee"
}

local L = {
	["LOAD"] = "Load",
	["RELOAD_UI"] = "Reload UI",
	["ENABLE_ALL"] = "Enable All",
	["DISABLE_ALL"] = "Disable All",
	["AUTHOR"] = "Author: %s",
	["VERSION"] = "Version: %s",
	["DEPENDENCIES"] = "Dependencies: %s",
	["DISABLED_AT_RELOAD"] = "Disabled on UI Reload",
	["LOAD_ON_DEMAND"] = "Loadable on Demand",
	["NOT_DEMAND_LOADED"] = "Not loadable on demand",
	["ADDON_MANAGEMENT"] = "Management",
	["NAME"] = "Name",
	["STATUS"] = "Status",
}

local function sortManagementAddons(a, b)
	if( not b ) then
		return false
	end

	if( frame.sortOrder ) then
		if( frame.sortType == "name" ) then
			return ( a.title < b.title )
		elseif( frame.sortType == "status" ) then
			return ( a.reason < b.reason )
		end

		return ( a.title < b.title )

	else
		if( frame.sortType == "name" ) then
			return ( a.title > b.title )
		elseif( frame.sortType == "status" ) then
			return ( a.reason > b.reason )
		end

		return ( a.title > b.title )
	end
end

local function createDependencies( ... )
	if( select("#", ...) == 0 ) then
		return nil
	end

	local deps = ""
	for i=1, select("#", ...) do
		if( i > 1 ) then
			deps = deps .. ", " .. select(i, ...)
		else
			deps = select(i, ...)
		end
	end

	return deps
end

local function createManageList()
	local searchBy = string.trim(string.lower(OptionHouseManageFrameSearch:GetText()))
	if( searchBy == "" or OptionHouseManageFrameSearch.searchText ) then
		searchBy = nil
	end

	frame.addons = {}
	for i=1, GetNumAddOns() do
		if( not searchBy or ( searchBy and string.find(string.lower((GetAddOnInfo(i))), searchBy) ) ) then
			local name, title, notes, enabled, loadable, reason, security = GetAddOnInfo(i)
			local isLoaded = IsAddOnLoaded(i)
			local isLoD = IsAddOnLoadOnDemand(i)
			local author = GetAddOnMetadata(i, "Author")
			local version = GetAddOnMetadata(i, "Version")
			local dependencies = createDependencies(GetAddOnDependencies(i))
			local dataTitle, dataAuthor, dataVersion = OptionHouse:GetAddOnData(name)
			local color
			
			title = dataTitle or title
			
			if( dataVersion ) then
				version = dataVersion
			elseif( type(version) == "string" ) then
				-- Strip out some of the common strings from version meta data
				version = string.gsub(version, "%$Revision: (%d+) %$", "%1")
				version = string.gsub(version, "%$Rev: (%d+) %$", "%1")
				version = string.gsub(version, "%$LastChangedRevision: (%d+) %$", "%1")
				version = string.trim(version)
			else
				version = nil
			end

			if( dataAuthor ) then
				author = dataAuthor
			elseif( type(author) ~= "string" ) then
				author = nil
			end

			if( reason == "DISABLED" ) then
				color = STATUS_COLORS[reason]
				reason = TEXT(ADDON_DISABLED)
				isLoD = nil

			-- Addons not LoD and was disabled
			elseif( reason == "NOT_DEMAND_LOADED" ) then
				color = STATUS_COLORS[reason]
				reason = L["NOT_DEMAND_LOADED"]

			elseif( loadable and isLoD and not isLoaded and enabled ) then
				reason = L["LOAD_ON_DEMAND"]
				color = STATUS_COLORS["LOAD_ON_DEMAND"]

			elseif( reason ) then
				reason = TEXT(getglobal("ADDON_" .. reason))
				color = STATUS_COLORS["ADDON_" .. reason]

			elseif( isLoaded and not enabled ) then
				reason = L["DISABLED_AT_RELOAD"]
				color = STATUS_COLORS["DISABLED_AT_RELOAD"]
				isLoD = nil

			-- Addon is LoD, but it was already loaded/enabled so dont show the button
			elseif( isLoD and isLoaded and enabled ) then
				reason = nil
				isLoD = nil
			end

			local tooltip = title

			if( author ) then
				tooltip = tooltip .. "\n" .. string.format(L["AUTHOR"], author)
			end

			if( version ) then
				tooltip = tooltip .. "\n" .. string.format(L["VERSION"], version)
			end

			if( dependencies ) then
				tooltip = tooltip .. "\n" .. string.format(L["DEPENDENCIES"], dependencies)
			end

			table.insert(frame.addons, {name = title, id = i, color = color, title = title, author = author, version = version, tooltip = tooltip, dependencies = dependencies, reason = reason or "", isEnabled = enabled, isLoD = isLoD})
		end
	end

	table.sort(frame.addons, sortManagementAddons)
end

local function updateManageList()
	if( not frame:IsShown() ) then
		return
	end

	FauxScrollFrame_Update(frame.scroll, #(frame.addons), TOTAL_ROWS, 22)

	for i=1, TOTAL_ROWS do
		local row = frame.rows[i]
		local offset = i + FauxScrollFrame_GetOffset(frame.scroll)
		local addon = frame.addons[offset]

		if( addon ) then
			if( addon.color ) then
				addon.reason = addon.color .. addon.reason .. "|r"
				addon.name = addon.color .. addon.name .. "|r"
			end

			row.name:SetText(addon.name)
			row.name:Show()

			row.enabled.text = addon.tooltip
			row.enabled.addon = addon.id
			row.enabled:SetChecked(addon.isEnabled)
			row.enabled:Show()

			row.reason:SetText(addon.reason)
			row.reason:Show()

			-- Shift the reason to the right if no button so we don't have ugly blank space
			if( not addon.isLoD ) then
				row.reason:SetPoint("RIGHT", row.button, "RIGHT", -5, 0)
				row.button:Hide()
			else
				row.reason:SetPoint("RIGHT", row.button, "LEFT", -5, 0)
				row.button.addon = addon.id
				row.button:Show()
			end
		else
			row.name:Hide()
			row.enabled:Hide()
			row.button:Hide()
			row.reason:Hide()
		end
	end
end

local function loadAddon(self)
	LoadAddOn(self.addon)

	createManageList()
	updateManageList()
end

local function toggleAddOnStatus(self)
	if( select(4, GetAddOnInfo(self.addon)) ) then
		PlaySound("igMainMenuOptionCheckBoxOff")
		DisableAddOn(self.addon)
	else
		PlaySound("igMainMenuOptionCheckBoxOn")
		EnableAddOn(self.addon)
	end

	createManageList()
	updateManageList()
end

local function showTooltip(self)
	if( self.text ) then
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
		GameTooltip:SetText(self.text, nil, nil, nil, nil, 1)
	end
end

local function hideTooltip()
	GameTooltip:Hide()
end

local function sortManageClick(self)
	if( self.sortType ) then
		if( self.sortType ~= frame.sortType ) then
			frame.sortOrder = false
			frame.sortType = self.sortType
		else
			frame.sortOrder = not frame.sortOrder
		end

		table.sort(frame.addons, sortManagementAddons)
		updateManageList()
	end
end

local function addonManageTab(hide)
	local name = "OptionHouseManageFrame"
	frame = getglobal(name)

	if( frame and hide ) then
		frame:Hide()
		return
	elseif( hide ) then
		return
	elseif( not frame ) then
		frame = CreateFrame("Frame", name, OptionHouseFrame)
		frame.sortOrder = true
		frame.sortType = "name"
		frame:SetFrameStrata("MEDIUM")
		frame:SetAllPoints(OptionHouseFrame)
		frame:RegisterEvent("ADDON_LOADED")
		frame:SetScript("OnEvent", function()
			createManageList()
			updateManageList()
		end )

		OptionHouse:CreateSearchInput(frame, function()
			createManageList()
			updateManageList()
		end )

		local disableAll = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
		disableAll:SetWidth(80)
		disableAll:SetHeight(22)
		disableAll:SetPoint("BOTTOMRIGHT", OptionHouseFrame, "BOTTOMRIGHT", -8, 14)
		disableAll:SetText(L["DISABLE_ALL"])
		disableAll:SetScript("OnClick", function()
			DisableAllAddOns()
			createManageList()
			updateManageList()
		end)

		local enableAll = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
		enableAll:SetWidth(80)
		enableAll:SetHeight(22)
		enableAll:SetPoint("RIGHT", disableAll, "LEFT")
		enableAll:SetText(L["ENABLE_ALL"])
		enableAll:SetScript("OnClick", function()
			EnableAllAddOns()
			createManageList()
			updateManageList()
		end)

		local reloadUI = CreateFrame("Button", nil, frame, "UIPanelButtonGrayTemplate")
		reloadUI:SetWidth(80)
		reloadUI:SetHeight(22)
		reloadUI:SetPoint("RIGHT", enableAll, "LEFT")
		reloadUI:SetText(L["RELOAD_UI"])
		reloadUI:SetScript("OnClick", ReloadUI)

		local button = CreateFrame("Button", name .. "SortButton1", frame)
		button:SetScript( "OnClick", sortManageClick)
		button:SetHeight(20)
		button:SetWidth(75)
		button:SetTextFontObject(GameFontNormal)
		button.sortType = "name"
		button:SetText(L["NAME"])
		button:SetWidth(button:GetFontString():GetStringWidth() + 3)
		button:SetPoint("TOPLEFT", frame, "TOPLEFT", 25, -73)
		button:Show()

		button = CreateFrame("Button", name .. "SortButton2", frame)
		button:SetScript( "OnClick", sortManageClick)
		button:SetHeight(20)
		button:SetWidth(75)
		button:SetTextFontObject(GameFontNormal)
		button.sortType = "status"
		button:SetText(L["STATUS"])
		button:SetWidth(button:GetFontString():GetStringWidth() + 3)
		button:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -50, -73)
		button:Show()
		
		local path, size, border = GameFontHighlightSmall:GetFont()
		size = OptionHouseDB.manageFontSize
		
		-- Setup a fake font string so we can figure out the fonts height
		local test = frame:CreateFontString()
		test:SetFont(path, size, border)
		test:SetText("*")
		
		-- Now figure out padding inbetween each row
		local spacing = -12 - test:GetHeight()		
		
		-- And now figure out how many rows we can support
		TOTAL_ROWS = ceil(305 / abs(spacing))
		
		frame.rows = {}
		for i=1, TOTAL_ROWS do
			local row = {}
			frame.rows[i] = row
			-- Enable checkbox
			row.enabled = CreateFrame("CheckButton", nil, frame, "OptionsCheckButtonTemplate")
			row.enabled:SetWidth(22)
			row.enabled:SetHeight(22)
			row.enabled:SetScript("OnClick", toggleAddOnStatus)
			row.enabled:SetScript("OnEnter", showTooltip)
			row.enabled:SetScript("OnLeave", hideTooltip)

			-- Load a LoD addon
			row.button = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
			row.button:SetWidth(50)
			row.button:SetHeight(18)
			row.button:SetText(L["LOAD"])
			row.button:SetScript("OnClick", loadAddon)

			-- Reason (Disabled/Not LoD/LoD/Dependency Missing/ect)
			row.reason = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
			row.reason:SetFont(path, size, border)

			-- Addon name
			row.name = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
			row.name:SetFont(path, size, border)
			row.name:SetHeight(22)
			row.name:SetJustifyH("LEFT")
			row.name:SetNonSpaceWrap(false)

			if( i > 1 ) then
				row.enabled:SetPoint("TOPLEFT", frame.rows[i-1].enabled, "TOPLEFT", 0, spacing)
				row.button:SetPoint("TOPRIGHT", frame.rows[i-1].button, "TOPRIGHT", 0, spacing)
				row.name:SetPoint("TOPLEFT", frame.rows[i-1].name, "TOPLEFT", 0, spacing)
				row.reason:SetPoint("RIGHT", frame.rows[i-1].button, "LEFT", -5, 0)
			else
				row.enabled:SetPoint("TOPLEFT", name .. "SortButton1", "TOPLEFT", 0, -22)
				row.button:SetPoint("TOPRIGHT", name .. "SortButton2", "TOPRIGHT", 4, -22)
				row.name:SetPoint("LEFT", row.enabled, "RIGHT", 5, 0)
				row.reason:SetPoint("RIGHT", row.button, "LEFT", -5, 0)
			end
		end

		frame.scroll = CreateFrame("ScrollFrame", name.."Scroll", frame, "FauxScrollFrameTemplate")
		frame.scroll:SetPoint("TOPLEFT", frame, "TOPLEFT", 25, -76)
		frame.scroll:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -35, 38)
		frame.scroll:SetScript("OnVerticalScroll", function() FauxScrollFrame_OnVerticalScroll(22, updateManageList) end)

		local texture = frame.scroll:CreateTexture(nil, "BACKGROUND")
		texture:SetWidth(31)
		texture:SetHeight(256)
		texture:SetPoint("TOPLEFT", frame.scroll, "TOPRIGHT", -2, 5)
		texture:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
		texture:SetTexCoord(0, 0.484375, 0, 1.0)

		local texture = frame.scroll:CreateTexture(nil, "BACKGROUND")
		texture:SetWidth(31)
		texture:SetHeight(106)
		texture:SetPoint("BOTTOMLEFT", frame.scroll, "BOTTOMRIGHT", -2, -2)
		texture:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
		texture:SetTexCoord(0.515625, 1.0, 0, 0.4140625)
	end

	createManageList()
	updateManageList()
	frame:Show()
end

-- For configuration
OHManage = {}
function OHManage:Register()
	if( not OptionHouse ) then
		OptionHouse = DongleStub("OptionHouse-1.0")
	end
	
	OptionHouse:RegisterTab(L["ADDON_MANAGEMENT"], addonManageTab, "bid")
end

--manageFontSize
function OHManage:Reload()

end

function OHManage:Unregister()
	if( OptionHouse ) then
		OptionHouse:UnregisterTab(L["ADDON_MANAGEMENT"])
	end
end
